tx <- readRDS("temp/tx_submitters.rds") |>
  filter(!bad_counties2) |> 
  select(!matches("_General_20"))

ballot_cols <- grep("^BallotType", names(tx))

# Iterate over the column indices
for (col_index in ballot_cols) {
  # Get the corresponding "Primary" column name
  primary_col <- sub("^BallotType_", "", names(tx)[col_index])
  
  # Replace values based on conditions
  tx[[col_index]][tx[[primary_col]] == "Y" & tx[[col_index]] == ""] <- "Unknown"
}

tx <- tx |> 
  mutate(across(starts_with("BallotType"), ~ case_when(. %in% c("Absentee", "Unknown", "Did Not Vote") ~ .,
                                                       . == "" ~ "Did Not Vote",
                                                       T ~ "In Person")))

l_long <- pivot_longer(tx, cols = starts_with("BallotT"), names_to = "year", values_to = "turnout") |> 
  mutate(year = as.integer(substring(year, 20, 23)),
         vote_mode = turnout,
         turnout = vote_mode != "Did Not Vote")

ll <- l_long |> 
  # filter(ballot_submitted) |>
  group_by(treated = (app_rejected_sb1), year) |> 
  summarize(turnout = mean(turnout))

ll$treated <- factor(ll$treated, levels = c(F, T))
ll$treated <- ifelse(ll$treated == "TRUE", "Rejection", "No Rejection")

ll_b <- l_long |> 
  filter(ballot_submitted) |>
  group_by(treated = (ballot_rejected_sb1), year) |> 
  summarize(turnout = mean(turnout))

ll_b$treated <- factor(ll_b$treated, levels = c(F, T))
ll_b$treated <- ifelse(ll_b$treated == "TRUE", "Rejection", "No Rejection")


ll <- bind_rows(ll |> 
                  mutate(group = "Application Rejected"),
                ll_b |> 
                  mutate(group = "Ballot Rejected"))

ggplot(filter(ll, year %% 4 != 2, year >= 2012, year != 2022), aes(x = year, y = turnout)) +
  facet_grid(. ~ group)  +
  geom_line(aes(linetype = treated), linewidth = 1) +
  geom_point(aes(shape = treated), size = 5) +
  theme_bc(legend.position = "bottom") +
  scale_linetype_manual(values = c("longdash", "solid")) +
  scale_y_continuous(labels = scales::percent) +
  scale_x_continuous(breaks = seq(2012, 2024, 4)) +
  geom_vline(xintercept = 2021.25, linetype = "solid", size = 1, color = "red") +
  annotate("text", x = 2018.8, y = 0.82, label = "2022 Primary", color = "black") +
  labs(y = "Turnout",
       x = "Election",
       shape = "Treatment Status",
       linetype = "Treatment Status",
       caption = "'Application Rejected' panel includes all individuals who submitted a mail ballot application for the 2022 primary. 'Ballot Rejected' panel includes those who submitted a mail ballot in the 2022 primary.
In all cases, 'No Rejection' refers to voters who did not have an application or ballot rejected in the primary of 2022; the inverse is true for the 'Rejection' voters. In other words, these groups remain constant across time.")

ggsave(paste0(out, "Figures/total_rej_fig_pri.png"), width = 6, height = 4, units = "in")

dat <- filter(l_long, year %% 4 != 2, year >= 2012, year != 2022) |> 
  mutate(group = ifelse(app_rejected_sb1, 1011, 0),
         group2 = ifelse(ballot_rejected_sb1, 1011, 0),
         period = year / 2,
         period = ifelse(period == 1012, 1011, period),
         time_to_treat = year - 2024,
         party = case_when(party < 0 ~ "D",
                           party == 0 ~ "I",
                           T ~ "R"))

m1 <- feols(turnout ~ app_rejected_sb1*(year == 2024) | LALVOTERID + year,
            filter(dat))

m1b <- feols(turnout ~ app_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS,
            filter(dat))

m1c <- feols(turnout ~ app_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS + year^Voters_Age,
             filter(dat))

m1d <- feols(turnout ~ app_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS + year^Voters_Age + year^party,
             filter(dat))

m2 <- feols(turnout ~ ballot_rejected_sb1*(year == 2024) | LALVOTERID + year,
            filter(dat, ballot_submitted))

m2b <- feols(turnout ~ ballot_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS,
             filter(dat, ballot_submitted))

m2c <- feols(turnout ~ ballot_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS + year^Voters_Age,
             filter(dat, ballot_submitted))

m2d <- feols(turnout ~ ballot_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS + year^Voters_Age + year^party,
             filter(dat, ballot_submitted))

#####################################

m1d_by <- feols(turnout ~ i(time_to_treat, app_rejected_sb1, ref = -4) | LALVOTERID + year^Voters_FIPS + year^party + year^Voters_Age,
             filter(dat))

m2d_by <- feols(turnout ~ i(time_to_treat, ballot_rejected_sb1, ref = -4) | LALVOTERID + year^Voters_FIPS + year^Voters_Age + year^party,
             filter(dat, ballot_submitted))


output <- rbindlist(lapply(list(m1d_by, m2d_by), function(mod){
  
  cints <- confint(mod) |> 
    rename(lb = `2.5 %`, ub = `97.5 %`) |> 
    mutate(year = c(2012, 2016, 2024),
           est = (lb + ub) / 2)
  
  cints$g <- ifelse(grepl("app", rownames(cints)), "app", "ballot")
  return(cints)
}))

output <- bind_rows(output,
                    data.table(year = c(2020, 2020),
                               est = 0,
                               g = c("app", "ballot"))) |> 
  mutate(c = factor(ifelse(year == 2024, "Post-Treatment", "Pre-Treatment"),
                    levels = c("Pre-Treatment", "Post-Treatment")))

ggplot(filter(output, g == "app"), aes(x = year, y = est, ymax = ub, ymin = lb, color = c)) +
  geom_point() +
  theme_bc() +
  geom_errorbar(width = 0) +
  scale_color_manual(values = c("black", "red")) +
  geom_vline(xintercept = 2020, linetype = "dashed") +
  geom_hline(yintercept = 0, linetype = "solid") +
  scale_x_continuous(breaks = seq(2012, 2024, 4)) +
  scale_y_continuous(labels = percent) +
  labs(x = "Year", y = "Estimated Treatment Effect", color = "",
       caption = "All years measured relative to 2020 (final pre-treatment primary election). Voter, year-county, year-age, and year-party fixed effects included. Standard errors clustered by voter.")
ggsave(paste0(out, "Figures/did_primary_app.png"), width = 6, height = 4, units = "in")

ggplot(filter(output, g == "ballot"), aes(x = year, y = est, ymax = ub, ymin = lb, color = c)) +
  geom_point() +
  theme_bc() +
  geom_errorbar(width = 0) +
  scale_color_manual(values = c("black", "red")) +
  geom_vline(xintercept = 2020, linetype = "dashed") +
  geom_hline(yintercept = 0, linetype = "solid") +
  scale_x_continuous(breaks = seq(2012, 2024, 4)) +
  scale_y_continuous(labels = percent) +
  labs(x = "Year", y = "Estimated Treatment Effect", color = "",
       caption = "All years measured relative to 2020 (final pre-treatment primary election). Voter, year-county, year-age, and year-party fixed effects included. Standard errors clustered by voter.")
ggsave(paste0(out, "Figures/did_primary_ballot.png"), width = 6, height = 4, units = "in")

###############################
###############################
###############################
###############################
cleanup(c("l_long", "tx", "m1", "m1b", "m1c", "m1d", 
          "m2", "m2b", "m2c", "m2d"))

ll <- l_long |> 
  filter(!(vote_mode %in% c("Did Not Vote", "Unknown"))) |> 
  group_by(treated = (app_rejected_sb1), year, vote_mode) |> 
  tally() |> 
  group_by(treated, year) |> 
  mutate(turnout = n / sum(n))

ll$treated <- factor(ll$treated, levels = c(F, T))
ll$treated <- ifelse(ll$treated == "TRUE", "Rejection", "No Rejection")

ll_b <- l_long |> 
  filter(ballot_submitted, !(vote_mode %in% c("Did Not Vote", "Unknown"))) |>
  group_by(treated = (ballot_rejected_sb1), year, vote_mode) |> 
  tally() |> 
  group_by(treated, year) |> 
  mutate(turnout = n / sum(n))

ll_b$treated <- factor(ll_b$treated, levels = c(F, T))
ll_b$treated <- ifelse(ll_b$treated == "TRUE", "Rejection", "No Rejection")


ll <- bind_rows(ll |> 
                  mutate(group = "Application Rejected"),
                ll_b |> 
                  mutate(group = "Ballot Rejected"))

ggplot(filter(ll, year %% 4 != 2, year >= 2012, year != 2022, vote_mode == "In Person"), aes(x = year, y = turnout)) +
  facet_grid(. ~ group)  +
  geom_line(aes(linetype = treated), linewidth = 1) +
  geom_point(aes(shape = treated), size = 5) +
  theme_bc(legend.position = "bottom") +
  scale_linetype_manual(values = c("longdash", "solid")) +
  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) +
  scale_x_continuous(breaks = seq(2012, 2024, 4)) +
  geom_vline(xintercept = 2022, linetype = "solid", size = 1, color = "red") +
  annotate("text", x = 2019.3, y = 1, label = "2022 Primary", color = "black") +
  labs(y = "Turnout",
       x = "Election",
       shape = "Treatment Status",
       linetype = "Treatment Status",
       caption = "'Application Rejected' panel includes all individuals who submitted a mail ballot application for the 2022 primary. 'Ballot Rejected' panel includes those who submitted a mail ballot in the 2022 primary.
In all cases, 'No Rejection' refers to voters who did not have an application or ballot rejected in the primary of 2022; the inverse is true for the 'Rejection' voters. In other words, these groups remain constant across time.")
ggsave(paste0(out, "Figures/primary_elections_vote_mode.png"), width = 6, height = 4, units = "in")


###############################
###############################
###############################
###############################


tow <- select(tx, LALVOTERID, starts_with("pred"), Primary_2012_05_29, Primary_2016_03_01,
              Primary_2020_03_03, party, Voters_Age, Voters_Gender, Voters_FIPS, dereg_primary,
              app_rejected_sb1,
              -pred.oth, -pred.nw) |> 
  mutate(across(starts_with("Prim"), ~ as.integer(. == "Y")),
         male = as.numeric(Voters_Gender == "M"),
         dereg_primary = as.numeric(dereg_primary)) |> 
  select(-Voters_Gender)

tow$Voters_FIPS <- as.factor(tow$Voters_FIPS)

counties <- data.frame(model.matrix( ~ Voters_FIPS - 1, data = tow ))

tow <- bind_cols(tow, counties) |> 
  select(-Voters_FIPS1, -Voters_FIPS)

tow <- tow[complete.cases(tow),]

mb <- ebalance(tow$app_rejected_sb1,
               select(tow, -app_rejected_sb1, -LALVOTERID))

saveRDS(mb, "temp/apps_primary_bal.rds")

mb <- readRDS("temp/apps_primary_bal.rds")

weights <- bind_rows(
  filter(tow, app_rejected_sb1) %>%
    mutate(weight = 1),
  filter(tow, !app_rejected_sb1) %>%
    mutate(weight = mb$w)
) |> 
  select(LALVOTERID, weight)

tx <- left_join(tx, weights)

l_long <- pivot_longer(tx, cols = starts_with("BallotT"), names_to = "year", values_to = "turnout") |> 
  mutate(year = as.integer(substring(year, 20, 23)),
         vote_mode = turnout,
         turnout = vote_mode != "Did Not Vote")

dat <- filter(l_long, year %% 4 != 2, year >= 2012, year != 2022) |> 
  mutate(group = ifelse(app_rejected_sb1, 1011, 0),
         group2 = ifelse(ballot_rejected_sb1, 1011, 0),
         period = year / 2,
         period = ifelse(period == 1012, 1011, period),
         time_to_treat = year - 2024)

m1e_by <- feols(turnout ~ i(time_to_treat, app_rejected_sb1, ref = -4) | LALVOTERID + year^Voters_FIPS + year^party + year^Voters_Age,
             filter(dat), weights = ~ weight)

output <- rbindlist(lapply(list(m1e_by), function(mod){
  
  cints <- confint(mod) |> 
    rename(lb = `2.5 %`, ub = `97.5 %`) |> 
    mutate(year = c(2012, 2016, 2024),
           est = (lb + ub) / 2)
  
  cints$g <- ifelse(grepl("app", rownames(cints)), "app", "ballot")
  return(cints)
}))

output <- bind_rows(output,
                    data.table(year = c(2020, 2020),
                               est = 0,
                               g = c("app", "ballot"))) |> 
  mutate(c = factor(ifelse(year == 2024, "Post-Treatment", "Pre-Treatment"),
                    levels = c("Pre-Treatment", "Post-Treatment")))

ggplot(filter(output, g == "app"), aes(x = year, y = est, ymax = ub, ymin = lb, color = c)) +
  geom_point() +
  theme_bc() +
  geom_errorbar(width = 0) +
  scale_color_manual(values = c("black", "red")) +
  geom_vline(xintercept = 2020, linetype = "dashed") +
  geom_hline(yintercept = 0, linetype = "solid") +
  scale_x_continuous(breaks = seq(2012, 2024, 4)) +
  scale_y_continuous(labels = percent) +
  labs(x = "Year", y = "Estimated Treatment Effect", color = "",
       caption = "All years measured relative to 2020 (final pre-treatment primary election). Voter, year-county, year-age, and year-party fixed effects included. Standard errors clustered by voter. Non-rejected voters entropy balanced using the following characteristics: predicted race; age; deregistration status; party; primary turnout (2012, 2016, 2020); county.")
ggsave(paste0(out, "Figures/did_primary_app_ebal.png"), width = 6, height = 4, units = "in")

m1e <- feols(turnout ~ app_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS + year^Voters_Age + year^party,
             filter(dat), weights = ~ weight)


rows <- tribble(~term,          ~m1,  ~m2, ~m3, ~m4, ~m5, ~m1,  ~m2, ~m3, ~m4,
                "Voter Fixed Effects", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$",
                "Year Fixed Effects", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$",
                "Year-County Fixed Effects", "", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$",
                "Year-Age Fixed Effects", "", "", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "", "", "$\\checkmark$", "$\\checkmark$",
                "Year-Party Fixed Effects", "", "", "", "$\\checkmark$", "$\\checkmark$", "", "", "", "$\\checkmark$",
                "Entropy Balanced", "", "", "", "", "$\\checkmark$", "", "", "", "")

attr(rows, 'position') <- c(3:8)

modelsummary(list(m1, m1b, m1c, m1d, m1e, 
                  m2, m2b, m2c, m2d),
             statistic = "std.error",
             stars = c("*" = 0.05, "**" = 0.01, "***" = 0.001),
             coef_map = c("app_rejected_sb1TRUE:year == 2024TRUE" = "Treated × 2024",
                          "ballot_rejected_sb1TRUE:year == 2024TRUE" = "Treated × 2024"),
             add_rows = rows,
             notes = list("Standard errors clustered by individual.",
                          "Includes 2012--2024 presidential primaries"),
             gof_omit = 'DF|Deviance|AIC|BIC|Within|Pseudo|Log|Std|FE|RMSE',
             title = "\\label{tab:did-reg-primary} Effect of a Primary Rejection on 2024 Primary Turnout",
             output = "latex",
             escape = FALSE) |> 
  add_header_above(c(" " = 1, "Application Rejected" = 5, "Ballot Rejected" = 4), align = "c") |> 
  # kable_styling(latex_options="scale_down") |> 
  save_kable(paste0(out, "Tables/did_reg_primary.tex"))

####################################################

dat <- filter(l_long, year %% 4 != 2, year >= 2012, year != 2022, !(vote_mode %in% c("Did Not Vote", "Unknown"))) |> 
  mutate(group = ifelse(app_rejected_sb1, 1011, 0),
         group2 = ifelse(ballot_rejected_sb1, 1011, 0),
         period = year / 2,
         period = ifelse(period == 1012, 1011, period),
         time_to_treat = year - 2024,
         party = case_when(party < 0 ~ "D",
                           party == 0 ~ "I",
                           T ~ "R"),
         turnout = vote_mode == "In Person")

m1 <- feols(turnout ~ app_rejected_sb1*(year == 2024) | LALVOTERID + year,
            filter(dat))

m1b <- feols(turnout ~ app_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS,
             filter(dat))

m1c <- feols(turnout ~ app_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS + year^Voters_Age,
             filter(dat))

m1d <- feols(turnout ~ app_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS + year^Voters_Age + year^party,
             filter(dat))


m2 <- feols(turnout ~ ballot_rejected_sb1*(year == 2024) | LALVOTERID + year,
            filter(dat, ballot_submitted))

m2b <- feols(turnout ~ ballot_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS,
             filter(dat, ballot_submitted))

m2c <- feols(turnout ~ ballot_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS + year^Voters_Age,
             filter(dat, ballot_submitted))

m2d <- feols(turnout ~ ballot_rejected_sb1*(year == 2024) | LALVOTERID + year^Voters_FIPS + year^Voters_Age + year^party,
             filter(dat, ballot_submitted))

rows <- tribble(~term,          ~m1,  ~m2, ~m3, ~m4, ~m1,  ~m2, ~m3, ~m4,
                "Voter Fixed Effects", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$",
                "Year Fixed Effects", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$",
                "Year-County Fixed Effects", "", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$", "", "$\\checkmark$", "$\\checkmark$", "$\\checkmark$",
                "Year-Age Fixed Effects", "", "", "$\\checkmark$", "$\\checkmark$", "", "", "$\\checkmark$", "$\\checkmark$",
                "Year-Party Fixed Effects", "", "", "", "$\\checkmark$", "", "", "", "$\\checkmark$")

attr(rows, 'position') <- c(3:7)

modelsummary(list(m1, m1b, m1c, m1d, 
                  m2, m2b, m2c, m2d),
             statistic = "std.error",
             stars = c("*" = 0.05, "**" = 0.01, "***" = 0.001),
             coef_map = c("app_rejected_sb1TRUE:year == 2024TRUE" = "Treated × 2024",
                          "ballot_rejected_sb1TRUE:year == 2024TRUE" = "Treated × 2024"),
             add_rows = rows,
             notes = list("Standard errors clustered by individual.",
                          "Includes 2012--2024 presidential primaries"),
             gof_omit = 'DF|Deviance|AIC|BIC|Within|Pseudo|Log|Std|FE|RMSE',
             title = "\\label{tab:did-reg-primary-behave} Effect of a Primary Rejection on Voting In-Person in 2024 Primary (Conditional on Voting)",
             output = "latex",
             escape = FALSE) |> 
  add_header_above(c(" " = 1, "Application Rejected" = 4, "Ballot Rejected" = 4), align = "c") |> 
  # kable_styling(latex_options="scale_down") |> 
  save_kable(paste0(out, "Tables/did_reg_primary_in_person.tex"))

#####################################

m1d <- feols(turnout ~ i(time_to_treat, app_rejected_sb1, ref = -4) | LALVOTERID + year^Voters_FIPS + year^party + year^Voters_Age,
             filter(dat))

m2d <- feols(turnout ~ i(time_to_treat, ballot_rejected_sb1, ref = -4) | LALVOTERID + year^Voters_FIPS + year^Voters_Age + year^party,
             filter(dat, ballot_submitted))


output <- rbindlist(lapply(list(m1d, m2d), function(mod){
  
  cints <- confint(mod) |> 
    rename(lb = `2.5 %`, ub = `97.5 %`) |> 
    mutate(year = c(2012, 2016, 2024),
           est = (lb + ub) / 2)
  
  cints$g <- ifelse(grepl("app", rownames(cints)), "app", "ballot")
  return(cints)
}))

output <- bind_rows(output,
                    data.table(year = c(2020, 2020),
                               est = 0,
                               g = c("app", "ballot"))) |> 
  mutate(c = factor(ifelse(year == 2024, "Post-Treatment", "Pre-Treatment"),
                    levels = c("Pre-Treatment", "Post-Treatment")))

ggplot(filter(output, g == "app"), aes(x = year, y = est, ymax = ub, ymin = lb, color = c)) +
  geom_point() +
  theme_bc() +
  geom_errorbar(width = 0) +
  scale_color_manual(values = c("black", "red")) +
  geom_vline(xintercept = 2020, linetype = "dashed") +
  geom_hline(yintercept = 0, linetype = "solid") +
  scale_x_continuous(breaks = seq(2012, 2024, 4)) +
  scale_y_continuous(labels = percent) +
  labs(x = "Year", y = "Estimated Treatment Effect", color = "",
       caption = "All years measured relative to 2020 (final pre-treatment primary election). Voter, year-county, year-age, and year-party fixed effects included. Standard errors clustered by voter.")
ggsave(paste0(out, "Figures/did_primary_app_in_person.png"), width = 6, height = 4, units = "in")

ggplot(filter(output, g == "ballot"), aes(x = year, y = est, ymax = ub, ymin = lb, color = c)) +
  geom_point() +
  theme_bc() +
  geom_errorbar(width = 0) +
  scale_color_manual(values = c("black", "red")) +
  geom_vline(xintercept = 2020, linetype = "dashed") +
  geom_hline(yintercept = 0, linetype = "solid") +
  scale_x_continuous(breaks = seq(2012, 2024, 4)) +
  scale_y_continuous(labels = percent) +
  labs(x = "Year", y = "Estimated Treatment Effect", color = "",
       caption = "All years measured relative to 2020 (final pre-treatment primary election). Voter, year-county, year-age, and year-party fixed effects included. Standard errors clustered by voter.")
ggsave(paste0(out, "Figures/did_primary_ballot_in_person.png"), width = 6, height = 4, units = "in")

############################################
############################################
############################################
############################################
